/**
 * creation: 18-jan-2008
 */
package org.jfonia.musicxml;

import java.util.ResourceBundle;

import org.w3c.dom.Node;

/**
 * Specialization of MusicXMLImportException for which the message is a code 
 * (which is typically the key to the actual error message in a resource bundle).
 * One can also specify a string parameter.
 * If the error message contains a character '@' then that character will be replaced
 * by the parameter.
 * @author Wijnand
 *
 */
public class CodedMusicXMLImportException extends MusicXMLImportException
{
	private static final long serialVersionUID = -3839212987091601939L;
	
	private static ResourceBundle errorMessages = null;

	// super.message holds the code which is used as a key in the resource bundle
	private String parameter = null;

	
	/**
	 * Sets the resourcebundle used for resolving errormessage codes.
	 */
	public static void setBundle(ResourceBundle bundle)
	{
		errorMessages = bundle;
	}

	/**
	 * Construct a CodedMusicXMLImportException using given code, param and node.
	 * @param code must be non null
	 * @param param optional parameter (may be null)
	 * @param node MusicXML DOM document node to which this exception pertains
	 */
	public CodedMusicXMLImportException(String code, String param, Node node)
	{
		super(code, node);
		this.parameter = param;
		if (code == null)
			throw new NullPointerException("code mustn't be null");
	}

	/**
	 * Construct a CodedMusicXMLImportException using given code, cause, param and node.
	 * @param code must be non null
	 * @param cause exception which caused this exception
	 * @param param optional parameter (may be null)
	 * @param node MusicXML DOM document node to which this exception pertains
	 */
	public CodedMusicXMLImportException(String code, Throwable cause, String param, Node node)
	{
		super(code, cause, node);
		this.parameter = param;
		if (code == null)
			throw new NullPointerException("code mustn't be null");
	}
	
	@Override
	public String toString() 
	{
		if (errorMessages == null)
			throw new RuntimeException("errorMessages resource bundle is not set.");
		
		StringBuffer sb = new StringBuffer();
		String code = this.getMessage();
		String msg = errorMessages.getString(code);
		if (msg != null)
		{
			// fill in parameter (message) in place of '@'
			int i = msg.indexOf('@');	
			if (i!=-1)
			{
				sb.append(msg.substring(0, i));
				sb.append(parameter);	// possibly "" or "null"
				sb.append(msg.substring(i+1));
			}
			else
				sb.append(msg);
		}
		else
		{
			sb.append("unknown exception '");
			sb.append(code);
			sb.append("'");
			if (parameter!=null)
			{
				sb.append(" with parameter '");
				sb.append(parameter); 
				sb.append("'");
			}
		}
		
		sb.append(super.getPositionInfo(this.getNode()));
		
		return sb.toString();
	}

	public void setParameter(String parameter)
	{
		this.parameter = parameter;
	}

	public String getParameter()
	{
		return parameter;
	}


}
